iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
Security

資安新手的試煉之路系列 第 26

資安新手的試煉之路 Day 26

  • 分享至 

  • xImage
  •  

今天來談談C語言與資安

C 語言的特性

C 語言是一種低階且非常高效的編程語言,最初於 1970 年代由 Dennis Ritchie 開發。它以其簡單、靈活且接近硬件層的特性,成為了系統編程、操作系統內核開發(如 UNIX 和 Linux 系統)的基礎。許多現代的編程語言(如 C++、Java)都基於 C 語言設計或受到其啟發。

然而,由於 C 語言的靈活性和低級別特性,程式員需要手動處理內存管理、指標操作等,這使得 C 語言在安全性方面面臨著特定的挑戰。這些挑戰若處理不當,可能會導致嚴重的安全漏洞,如緩衝區溢出(Buffer Overflow)、指標操作錯誤等。


C 語言中的常見資安問題

  1. 緩衝區溢出(Buffer Overflow)

    緩衝區溢出是 C 語言最常見的安全問題之一。當程式試圖將超出緩衝區容量的數據寫入內存時,會覆蓋緩衝區之外的數據,導致程序崩潰甚至允許攻擊者執行惡意代碼。這一漏洞曾在許多經典攻擊中被利用。

    範例:

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        char buffer[10];
        strcpy(buffer, "This is a long string");
        printf("%s\n", buffer);
        return 0;
    }
    

    這段程式會嘗試將超過 buffer 容量的字符串寫入,導致緩衝區溢出,可能引發未定義行為。

    防範措施

    • 使用更安全的函數如 strncpy()snprintf() 等,來限制輸入數據的長度。
    • 引入地址隨機化技術(ASLR)和堆棧保護技術來減少漏洞利用的可能性。
  2. 格式化字符串攻擊(Format String Attack)

    在 C 語言中,格式化字符串攻擊通常發生在 printf()scanf() 這類函數使用不當時。若攻擊者控制了格式化字符串的輸入,他們可以通過這一漏洞訪問內存數據甚至執行代碼。

    範例:

    #include <stdio.h>
    
    int main() {
        char input[100];
        gets(input);  // 假設使用者輸入
        printf(input);  // 不安全
        return 0;
    }
    

    在這個例子中,如果 input 包含特定格式符,如 %x%n,攻擊者可能通過這些符號讀取內存內容或改變內存的值。

    防範措施

    • 始終使用安全的格式化函數,例如 printf("%s", input),而不是直接使用非格式化輸入的字符串。
    • 使用更嚴格的輸入驗證和過濾。
  3. 指標操作錯誤(Pointer Errors)

    C 語言允許直接操作指標,這一特性雖然強大,但也可能引發嚴重的資安問題。如果程序員誤用或未正確檢查指標,可能會導致空指標引用(NULL Pointer Dereference)或野指標(Dangling Pointer),這些都可能被攻擊者利用來進行惡意攻擊。

    範例:

    int *ptr = NULL;
    *ptr = 10;  // 空指標引用
    

    防範措施

    • 在使用指標前檢查其是否為空(NULL)。
    • 小心管理動態內存分配,避免使用已經釋放的指標。
    • 適當使用智能指標(在 C++ 中)或手動實現資源管理。
  4. 動態內存管理漏洞(Memory Management Issues)

    在 C 語言中,動態內存分配與釋放需要手動管理。若忘記釋放內存或過早釋放,可能導致內存洩漏(Memory Leak)或使用已釋放內存(Use-After-Free)漏洞,這些都可能使系統不穩定或被攻擊者利用來竊取數據或控制系統。

    範例:

    char *data = (char *)malloc(10);
    free(data);
    // 使用已釋放的內存
    strcpy(data, "unsafe");
    

    防範措施

    • 確保每次分配內存都有對應的釋放操作。
    • 使用工具如 Valgrind 來檢測內存洩漏或不當的內存操作。
    • 避免使用已釋放的指標。

C 語言中常用的安全技術

  1. 代碼審查與靜態分析工具

    • 靜態分析工具(如 Coverity、Fortify、Splint)可幫助開發者在編寫 C 程式時,檢查可能存在的安全漏洞,如緩衝區溢出、空指標引用等。
    • 定期的 代碼審查 可在早期階段發現漏洞並進行修補。
  2. 內存保護技術

    • 堆棧保護(Stack Canaries):這是一種在編譯時插入保護位元的方法,防止堆棧溢出攻擊破壞返回地址。
    • 地址隨機化(ASLR):通過隨機化進程的內存佈局,使攻擊者難以猜測關鍵內存位置。
    • DEP(Data Execution Prevention):防止代碼在數據段執行,以防止緩衝區溢出攻擊注入並執行惡意代碼。
  3. 編譯器安全選項

    • 在編譯 C 程序時,可以使用一些編譯器選項來增強安全性:
      • -fstack-protector: 開啟堆棧保護。
      • -D_FORTIFY_SOURCE=2: 增強了函數如 printf()strcpy() 的檢查,防止緩衝區溢出。
      • -Wl,-z,relro,-z,now: 使用 RELRO 和 NOW 保護來防止一些動態連結器的攻擊。

C 語言在資安領域的應用

  1. 開發安全工具
    C 語言因為其高效和接近硬件層的特性,被廣泛用於開發資安工具和系統軟件,包括防火牆、入侵檢測系統(IDS)、漏洞掃描器等。

  2. 漏洞研究與開發
    許多安全研究人員使用 C 語言來開發漏洞利用代碼(Exploit)或進行漏洞研究,特別是在針對操作系統和內核的攻擊中,C 語言的低階特性使其成為首選語言。

  3. 嵌入式系統與 IoT 安全
    C 語言在嵌入式系統和物聯網(IoT)設備中有廣泛應用。然而,這些設備通常資源有限,C 語言的使用可能增加安全風險。因此,進行這類系統的資安測試時,C 語言相關的漏洞如緩衝區溢出尤為常見。


結論

C 語言由於其低階、靈活和高效的特性,在操作系統、嵌入式系統等領域擁有廣泛的應用。然而,由於其內存管理和指標操作的手動控制,導致 C 語言存在較多的安全挑戰。正確地使用 C 語言、遵循安全編程原則、使用現代編譯器保護技術以及定期進行代碼審查,可以有效減少潛在的資安風險。


上一篇
資安新手的試煉之路Day 25
下一篇
資安新手的試煉之路Day 27
系列文
資安新手的試煉之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言